using System;
using System.BusinessObjects.Data;
using System.Data;
using System.Xml.Serialization;
using Iesi.Collections.Generic;
using System.BusinessObjects.Validation;

namespace Blazing.BusinessObjects.Tagging
{
    /// <summary>
    /// A container object for managing Taxonomy-Tag relationships
    /// </summary>
    [Serializable]
	public class TaxonomyTag : DataObject<TaxonomyTag>
	{
        public virtual int ID
        {
            get { return GetValue<int>("ID"); }
            set
            {
                BeginEdit();
                SetValue("ID", value);
            }
        }

        [XmlIgnore]
        public virtual string InternalName
        {
            get
            {
                return string.Format("{0} ({1})", Tag != null ? Tag.Name : "", Taxonomy != null ? Taxonomy.Name : "");
            }
        }

        [NonSerialized]
        private Tag _tag;
        public virtual Tag Tag
        {
            get { return _tag; }
            set { BeginEdit(); _tag = value; }
        }

        [NonSerialized]
        Taxonomy _taxonomy;
        public virtual Taxonomy Taxonomy
        {
            get
            {
                return _taxonomy;
            }
            set
            {
                BeginEdit();
                _taxonomy = value;
            }
        }

        public virtual string Description
        {
            get { return GetValue<string>("Description"); }
            set
            {
                BeginEdit();
                SetValue("Description", value);
            }
        }

        public virtual int Count
        {
            get { return GetValue<Int32>("Count"); }
            set
            {
                BeginEdit();
                SetValue("Count", value);
            }
        }

        public virtual bool IsSelectable
        {
            get { return GetValue<bool>("IsSelectable"); }
            set
            {
                BeginEdit();
                SetValue("IsSelectable", value);
            }
        }

        public virtual bool IsVisible
        {
            get { return GetValue<bool>("IsVisible"); }
            set
            {
                BeginEdit();
                SetValue("IsVisible", value);
            }
        }

        [NonSerialized]
        TaxonomyTag _parentTaxonomyTag;
        public virtual TaxonomyTag ParentTaxonomyTag
        {
            get
            {
                return _parentTaxonomyTag;
            }
            set
            {
                BeginEdit();
                _parentTaxonomyTag = value;
            }
        }

        [NonSerialized]
        ISet<TaxonomyTag> _childTaxonomyTags = new HashedSet<TaxonomyTag>();
        public virtual ISet<TaxonomyTag> ChildTaxonomyTags 
        {
            get
            {
                return _childTaxonomyTags;
            }
            set
            {
                BeginEdit();
                _childTaxonomyTags = value;
            }
        }

        public virtual string Slug
        {
            get { return GetValue<string>("Slug"); }
            set
            {
                BeginEdit();
                SetValue("Slug", value);
            }
        }

        public virtual bool ChildrenMutuallyExclusive
        {
            get { return GetValue<bool>("ChildrenMutuallyExclusive"); }
            set
            {
                BeginEdit();
                SetValue("ChildrenMutuallyExclusive", value);
            }
        }

        public virtual DateTime RowStamp
        {
            get { return GetValue<DateTime>("RowStamp"); }
            set
            {
                SetValue("RowStamp", value);
            }
        }

        protected override void AddValidationRules()
        {
            validationRules.Add(new ValidationRule(ValidationRuleCanNotSetParentToSelf()));
        }

        public virtual ValidatorTemplate ValidationRuleCanNotSetParentToSelf()
        {
            System.Reflection.PropertyInfo parentInfo = GetType().GetProperty("ParentTaxonomyTag");
            ValidatorTemplate parentIsNotSelf = delegate(out string propName, out string message)
            {
                propName = "ParentTaxonomyTag";
                bool retval = true;
                message = string.Empty;
                object curVal = parentInfo.GetValue(this, null);
                if (curVal != null)
                {
                    if (((TaxonomyTag)curVal).ID == ID)
                    {
                        message = string.Format("Taxonomy Tags's parent can not be set to itself  #{0}", ID);
                        retval = false;
                    }
                }
                return retval;
            };

            return parentIsNotSelf;
        }
	}
}
